home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / µSim 1.1 / FabLibsƒ / SoundHandling.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-28  |  3.3 KB  |  151 lines  |  [TEXT/CWIE]

  1. #include    <string.h>
  2.  
  3. #include    "FabWmemman.h"
  4. #include    "FabTaskManager.h"
  5. #include    "SoundHandling.h"
  6.  
  7. static SndCallBackUPP    gmyCallbackUPP = nil;
  8. static unsigned int    gNumAsyncSnds = 0;
  9.  
  10. static pascal void myCallback(SndChannelPtr theChan, const SndCommand *sc);
  11. static void CloseSoundChannel(void *sndChan);
  12. static void GetRidOfSndChannel(SndChannelPtr sndChan);
  13. static void NewSoundData(SndListHandle sndH);
  14. static Boolean IncrementSnd(SndListHandle sndH);
  15. static void DeleteSoundData(SndListHandle sndH);
  16.  
  17. unsigned short GetSoundsRemaining(void)
  18. {
  19. return gNumAsyncSnds;
  20. }
  21.  
  22. void InitMySoundHandling(void)
  23. {
  24. gmyCallbackUPP = NewSndCallBackProc(myCallback);
  25. }
  26.  
  27. pascal void myCallback(SndChannelPtr /*theChan*/, const SndCommand *sc)
  28. {
  29. Fab_ScheduleSystemTask((void *)sc->param2);
  30. }
  31.  
  32. void DoSound(short sndResID)
  33. {
  34. SndListHandle    sndH;
  35.  
  36. if (sndH = (SndListHandle)Get1Resource(soundListRsrc, sndResID))
  37.     DoSoundHandle(sndH);
  38. }
  39.  
  40. void DoSoundHandle(SndListHandle sndH)
  41. {
  42. enum {
  43. kMyQueueLen = 4
  44. };
  45. SndCommand    mySndCmd;
  46. SndChannelPtr    mySndChan;
  47.  
  48. mySndChan = (SndChannelPtr)fmalloc(sizeof(SndChannel) - stdQLength * sizeof(SndCommand) + kMyQueueLen * sizeof(SndCommand));
  49. if (mySndChan) {
  50.     mySndChan->qLength = kMyQueueLen;
  51.     if (SndNewChannel(&mySndChan, 0, 0, gmyCallbackUPP) == noErr) {
  52.         mySndChan->userInfo = (long)sndH;
  53.         mySndCmd.cmd = callBackCmd;
  54.         mySndCmd.param2 = (long)Fab_CreateSystemTask(CloseSoundChannel, mySndChan, true);
  55.         if (mySndCmd.param2) {
  56.             NewSoundData(sndH);
  57.             (void) SndPlay(mySndChan, sndH, true);
  58.             ++gNumAsyncSnds;
  59. //            InitTaskRecord(CloseSoundChannel, (TMInfoPtr)mySndCmd.param2);
  60.             (void)SndDoCommand(mySndChan, &mySndCmd, true);
  61.             }
  62.         else
  63.             GetRidOfSndChannel(mySndChan);
  64.         }
  65.     }
  66. }
  67.  
  68. void CloseSoundChannel(void *sndChan)
  69. {
  70. --gNumAsyncSnds;
  71. DeleteSoundData((SndListHandle)((SndChannelPtr)sndChan)->userInfo);
  72. GetRidOfSndChannel((SndChannelPtr)sndChan);
  73. }
  74.  
  75. static void GetRidOfSndChannel(SndChannelPtr sndChan)
  76. {
  77. (void)SndDisposeChannel(sndChan, false);
  78. ffree((Ptr)sndChan);
  79. }
  80.  
  81.  
  82. enum {
  83. kInitialSlots = 8
  84. };
  85.  
  86. struct CountLocks {
  87.     SndListHandle    sndH;
  88.     UInt32            count;
  89. };
  90.  
  91. typedef struct CountLocks CountLocks;
  92.  
  93. static Handle    gWarr = nil;
  94. static int    gWcount = 0, gWmaxcount = kInitialSlots;
  95.  
  96. void NewSoundData(SndListHandle sndH)
  97. {
  98. if (IncrementSnd(sndH) == false) {
  99.     if (gWarr == nil) {
  100.         gWarr = NewHandle(sizeof(CountLocks) * kInitialSlots);
  101.         }
  102.     else if (gWcount == gWmaxcount) {
  103.         gWmaxcount += kInitialSlots;
  104.         SetHandleSize(gWarr, sizeof(CountLocks) * gWmaxcount);
  105.         }
  106.  
  107.     ((CountLocks *)(*gWarr))[gWcount].sndH = sndH;
  108.     ((CountLocks *)(*gWarr))[gWcount++].count = 1;
  109.     HLockHi((Handle)sndH);
  110.     }
  111. }
  112.  
  113. Boolean IncrementSnd(SndListHandle sndH)
  114. {
  115. CountLocks        *deref;
  116. int    i;
  117.  
  118. if (gWarr) {
  119.     deref = (CountLocks *)*gWarr;
  120.     for (i = 0; i < gWcount; i++)
  121.         if (sndH == deref[i].sndH) {
  122.             ++(deref[i].count);
  123.             return true;
  124.             }
  125.     }
  126. return false;
  127. }
  128.  
  129. void DeleteSoundData(SndListHandle sndH)
  130. {
  131. CountLocks        *deref;
  132. int        i;
  133. int        newCount;
  134.  
  135. deref = (CountLocks *)*gWarr;
  136. // find sound in array
  137. for (i = 0; i < gWcount; i++)
  138.     if (sndH == deref[i].sndH) {
  139. // move items
  140.         if (--(deref[i].count) == 0) {
  141.             newCount = gWcount - 1;
  142.             if (i != newCount)
  143.                 (void) memmove(&deref[i], &deref[i+1], (newCount - i) * sizeof(CountLocks));
  144.             gWcount = newCount;    // updated last to avoid concurrency problems
  145.             HUnlock((Handle)sndH);
  146.             }
  147.         break;
  148.         }
  149. }
  150.  
  151.